package fractal;

import jinyilw.common.ArrayTools;
import jinyilw.common.file.FileTools;
import jinyilw.swing.ColorTools;
import jinyilw.swing.SwingTools;
import jinyilw.swing.hint.HintWindow;
import jinyilw.swing.i18n.ICSetting;
import jinyilw.swing.i18n.IString;
import jinyilw.swing.i18n.ITexts;
import jinyilw.swing.rlaf.ui.RLayoutAdapter;
import jinyilw.swing.visuals.Icomp.IButton;
import jinyilw.swing.visuals.Icomp.IFileChooser;
import jinyilw.swing.visuals.Rcomp.RDialog;
import jinyilw.swing.visuals.Rcomp.ROptionPane;
import jinyilw.swing.visuals.comp.ColorComp;

import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

public class GradientColorDialog extends RDialog
{
	private static final long serialVersionUID = -1146405957304106530L;
	private static final String graPath = "gra";
	FractalFrame fractalFrame;
	Color[] gradualColors;
	ColorComp[] cButtons;
	List<GradientLabel> gradientLabels;
	List<File> gradientFiles;
	JPanel setPanel;

	public GradientColorDialog(FractalFrame owner)
	{
		super(owner.tzDialog);
		fractalFrame = owner;
		gradualColors = owner.gradualColors;
		init();
	}

	private void init()
	{
		setTitle(new ICSetting("setGradientColor", "设置渐变色",
				"Set gradient color"), true);
		setTitleColor(Color.yellow);
		setOptionStyle(180, 0.8f);
		setResizable(false);
		setAlwaysOnTop(true);
		Container container = getContentPane();
		container.setLayout(new GCDLayout());
		gradientLabels = new ArrayList<>();

		setPanel = SwingTools.createTransBorderPane();
		setPanel.setLayout(null);
		setPanel.setSize(180, 60);
		container.add(setPanel);
		ColorActionListener colorActionListener = new ColorActionListener();
		cButtons = new ColorComp[4];
		for (int i = 0; i < cButtons.length; i++)
		{
			cButtons[i] = new ColorComp();
			setPanel.add(cButtons[i]);
			cButtons[i].setBounds(15 + i * 40, 5, 30, 20);
			cButtons[i].addMouseListener(colorActionListener);
		}
		IButton sButton = new IButton();
		sButton.setText(new ICSetting("save", "保存", "Save"), true);
		sButton.setBounds(20, 30, 60, 22);
		setPanel.add(sButton);
		IButton oButton = new IButton();
		oButton.setText(new ICSetting("open", "打开", "Open"), true);
		oButton.setBounds(100, 30, 60, 22);
		setPanel.add(oButton);
		sButton.addActionListener(new ActionListener()
		{
			IFileChooser graSaveChooser = null;

			@Override
			public void actionPerformed(ActionEvent e)
			{
				dispose();
				if (graSaveChooser == null)
				{
					IString iTitle = new IString("saveGraTitle", "保存当前渐变色",
							"Save current gradual colors");
					graSaveChooser = new IFileChooser(FileTools.getUserFile("gra"),
							"gra", iTitle);
				}
				saveGraFile(graSaveChooser.openAndGetSaveFile(fractalFrame));
			}
		});

		oButton.addActionListener(new ActionListener()
		{
			IFileChooser graOpenChooser = null;

			@Override
			public void actionPerformed(ActionEvent e)
			{
				dispose();
				if (graOpenChooser == null)
				{
					IString iTitle = new IString("openGraTitle", "打开渐变色",
							"Open gradual colors");
					graOpenChooser = new IFileChooser(FileTools.getUserFile("gra"),
							"gra", iTitle);
				}
				openGraFile(graOpenChooser.openAndGetOpenFile(fractalFrame));
			}
		});
	}

	public void update()
	{
		Container container = getContentPane();
		List<File> newGraFiles = FileTools.getAllTypeFile(graPath, ".gra");
		List<File> graFiles = ArrayTools.getNew(newGraFiles, gradientFiles);
		for (File file : graFiles)
		{
			GradientLabel gLabel = new GradientLabel(file);
			if (gLabel.colors[3] != null)
			{
				container.add(gLabel);
				gradientLabels.add(gLabel);
			}
		}
		gradientFiles = newGraFiles;
		for (int i = 0; i < cButtons.length; i++)
			cButtons[i].setBackground(gradualColors[i]);
		pack();
	}

	private class GCDLayout extends RLayoutAdapter
	{
		@Override
		public Dimension preferredLayoutSize(Container parent)
		{
			int width = setPanel.getWidth();
			int height = gradientLabels.size() * 25 + setPanel.getHeight() + 5;
			return new Dimension(width, height);
		}

		@Override
		public Dimension minimumLayoutSize(Container parent)
		{
			return preferredLayoutSize(parent);
		}

		@Override
		public void layoutContainer(Container parent)
		{
			int x = (parent.getWidth() - 150) / 2, y = 5;
			for (GradientLabel gLabel : gradientLabels)
			{
				gLabel.setLocation(x, y);
				y += 25;
			}
			setPanel.setLocation(0, y);
		}
	}

	private class GradientLabel extends ColorComp
	{
		private static final long serialVersionUID = 1916427068584628222L;
		Color[] colors;

		public GradientLabel(File f)
		{
			setSize(150, 18);
			colors = new Color[4];
			DataInputStream dis = null;
			try
			{
				dis = new DataInputStream(new FileInputStream(f));
				for (int i = 0; i < colors.length; i++)
					colors[i] = new Color(dis.readInt());
				dis.close();
			} catch (Exception e1)
			{
				try
				{
					if (dis != null)
						dis.close();
				} catch (Exception ignored)
				{
				}
			}
			setGradientColors(colors);
			addMouseListener(new MouseAdapter()
			{
				@Override
				public void mouseClicked(final MouseEvent e)
				{
					dispose();
					ArrayTools.copy(colors, gradualColors);
					// copyColors(gradualColors);
					fractalFrame.setToBeGradientType();
					for (int i = 0; i < cButtons.length; i++)
					{
						cButtons[i].setBackground(gradualColors[i]);
						// System.out.println(gradualColors[i].getRGB());
					}
				}
			});
		}
	}

	public void saveGraFile(File f)
	{
		if (f == null)
			return;
		DataOutputStream dos = null;
		try
		{
			dos = new DataOutputStream(new FileOutputStream(f));
			for (Color gradualColor : gradualColors)
				dos.writeInt(gradualColor.getRGB());
			dos.close();
		} catch (Exception e1)
		{
			e1.printStackTrace();
			try
			{
				if (dos != null)
					dos.close();
			} catch (Exception ignored)
			{
			}
			HintWindow.showHint(ITexts.fileErrString, fractalFrame);
		}
		HintWindow.showHint(ITexts.saveOkString, fractalFrame);
	}

	IString openGraError = new IString("openGraError", "打开gra文件出错！",
			"gra file error!");

	public void openGraFile(File f)
	{
		if (f == null)
			return;
		DataInputStream dis = null;
		try
		{
			dis = new DataInputStream(new FileInputStream(f));
			for (int i = 0; i < gradualColors.length; i++)
				gradualColors[i] = new Color(dis.readInt());
			dis.close();
		} catch (Exception e1)
		{
			ROptionPane.showMessageDialog(this, openGraError,
					ITexts.fileErrString);
			if (dis != null)
				try
				{
					dis.close();
				} catch (Exception ignored)
				{
				}
			return;
		}
		fractalFrame.setToBeGradientType();
		for (int i = 0; i < cButtons.length; i++)
			cButtons[i].setBackground(gradualColors[i]);
	}

	private class ColorActionListener extends MouseAdapter
	{
		IString setGradientString = new IString("setGradient", "设置渐变颜色",
				"Set gradient color");

		@Override
		public void mouseClicked(final MouseEvent e)
		{
			ColorComp button = (ColorComp) e.getSource();
			Color color = ColorTools.showDefaultColorDialog(null,
					setGradientString, null);
			if (color != null && !color.equals(button.getBackground()))
			{
				button.setBackground(color);
				for (int i = 0; i < cButtons.length; i++)
					if (button == cButtons[i])
					{
						gradualColors[i] = color;
						break;
					}
				fractalFrame.setToBeGradientType();
			}
			dispose();
		}
	}
}
